home *** CD-ROM | disk | FTP | other *** search
/ PC Elektro 3 / PC-Elektro-3-cd1.bin / KBan 2.0 / KBANSRC.LZH / SRC / PROG / KBANDATA / LINELIST.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-07  |  9.6 KB  |  387 lines

  1. // the implementation of class LINE_LIST
  2. // Copyright (C) 1996, 1997 Kazutaka Hirata <khirata@jove.acs.unt.edu>
  3.  
  4. #include "../kbandef.h"
  5.  
  6. #include "linelist.h"
  7.  
  8. XY LINE_LIST::get_max() const
  9. {
  10.   XY ac_max(X_MIN, Y_MIN);
  11.   iterator i;
  12.   TRAVERSE(*this, i) {
  13.     ac_max = ::get_max(ac_max, i->get_max());
  14.   }
  15.   return ac_max;
  16. }
  17.  
  18. XY LINE_LIST::get_min() const
  19. {
  20.   XY ac_min(X_MAX, Y_MAX);
  21.   iterator i;
  22.   TRAVERSE(*this, i) {
  23.     ac_min = ::get_min(ac_min, i->get_min());
  24.   }
  25.   return ac_min;
  26. }
  27.  
  28. void LINE_LIST::shift(const XY& ac_dif, LINE_LIST& target) const
  29. {
  30.   iterator i;
  31.   TRAVERSE(*this, i) {
  32.     target.push_back(i->shift(ac_dif));
  33.   }
  34. }
  35.  
  36. void LINE_LIST::unselect()
  37. {
  38.   iterator i;
  39.   TRAVERSE(*this, i) {
  40.     i->unselect();
  41.   }
  42. }
  43.  
  44. void LINE_LIST::select_items_in_block(const XY& ac1, const XY& ac2)
  45. {
  46.   iterator i;
  47.   TRAVERSE(*this, i) {
  48.     if(i->is_in_block(ac1, ac2)) {
  49.       i->select();
  50.     }
  51.   }
  52. }
  53.  
  54. void LINE_LIST::collect_selected_items(LINE_LIST& dst) const
  55. {
  56.   iterator i;
  57.   TRAVERSE(*this, i) {
  58.     if(i->is_selected()) {
  59.       dst.push_back(*i);
  60.     }
  61.   }
  62. }
  63.  
  64. void LINE_LIST::remove_selected_items()
  65. {
  66.   iterator i;
  67.   TRAVERSE(*this, i) {
  68.     if(i->is_selected()) {
  69.       iterator current_i = i--;
  70.       erase(current_i);
  71.     }
  72.   }
  73. }
  74.  
  75. void LINE_LIST::collect_aperture(APT_TABLE& apt_table) const
  76. {
  77.   iterator i;
  78.   TRAVERSE(*this, i) {
  79.     APERTURE apt(APERTURE::APT_ROUND, i->width(), 0, 0);
  80.     if(!apt_table.is_included(apt)) {
  81.       apt_table.push_back(apt);
  82.     }
  83.   }
  84. }
  85.  
  86. int LINE_LIST::save(FILE_NEW& fp) const
  87. {
  88.   FILE_VERSION fver;
  89.   fp.printf("%s\n", fver.get_version_str(FILE_VERSION::VERSION_200A8));
  90.  
  91.   iterator i;
  92.   TRAVERSE(*this, i) {
  93.     i->save_200a8(fp);
  94.   }
  95.  
  96.   fp.puts("end\n");
  97.   return true;
  98. }
  99.  
  100. int LINE_LIST::load_primitive_170(FILE_NEW& fp)
  101. {
  102.   for(;;) {
  103.     LINE_ELEMENT element;
  104.     char str[1024];
  105.     fp.gets_wo_return(str, 1024);
  106.     if(!strcmp(str, "end")) {
  107.       break;
  108.     }
  109.     element.load_primitive_170(str);
  110.     push_back(element);
  111.   }
  112.   return true;
  113. }
  114.  
  115. int LINE_LIST::load_component_170(FILE_NEW& fp)
  116. {
  117.   for(;;) {
  118.     LINE_ELEMENT element;
  119.     char str[1024];
  120.     fp.gets_wo_return(str, 1024);
  121.     if(!strcmp(str, "end")) {
  122.       break;
  123.     }
  124.     element.load_component_170(str);
  125.     push_back(element);
  126.   }
  127.   return true;
  128. }
  129.  
  130. uint LINE_LIST::load_get_version(FILE_NEW& fp) const
  131. {
  132.   FILE_VERSION fver;
  133.   char str[1024];
  134.   fp.gets_wo_return(str, 1024);
  135.   return fver.get_version_no(str);
  136. }
  137.  
  138. LINE_LIST::LOAD_FUNC_INFO LINE_LIST::load_func_table[] = {
  139.   {FILE_VERSION::VERSION_200A8  , &LINE_ELEMENT::load_200a8},
  140.   {FILE_VERSION::VERSION_UNKNOWN, NULL                     }
  141. };
  142.  
  143. LINE_LIST::LOAD_FUNC LINE_LIST::get_load_func(uint version) const
  144. {
  145.   uint sentinel = FILE_VERSION::VERSION_UNKNOWN;
  146.   uint index = search_info_table(load_func_table, sentinel, version);
  147.   return load_func_table[index].func;
  148. }
  149.  
  150. int LINE_LIST::load(FILE_NEW& fp)
  151. {
  152.   int retval;
  153.   uint version = load_get_version(fp);
  154.   LOAD_FUNC load_func = get_load_func(version);
  155.   if(load_func != NULL) {
  156.     clear();
  157.     for(;;) {
  158.       LINE_ELEMENT element;
  159.       char str[1024];
  160.       fp.gets_wo_return(str, 1024);
  161.       if(!strcmp(str, "end")) {
  162.         break;
  163.       }
  164.       (element.*load_func)(str);
  165.       push_back(element);
  166.     }
  167.     retval = true;
  168.   } else {
  169.     retval = false;
  170.   }
  171.   return retval;
  172. }
  173.  
  174. bool LINE_LIST::is_there_nearest_point(XYT ac_min, const XY& ac) const
  175. {
  176.   bool ret = false;
  177.   iterator i;
  178.   TRAVERSE(*this, i) {
  179.     int r = maximum(i->width() / 2, (uint)ac_min);
  180.     if(compare_distance_lt(ac, i->ac_s(), r)) {
  181.       ret = true;
  182.       break;
  183.     }
  184.     if(compare_distance_lt(ac, i->ac_e(), r)) {
  185.       ret = true;
  186.       break;
  187.     }
  188.   }
  189.   return ret;
  190. }
  191.  
  192. XY LINE_LIST::search_nearest_point(XYT ac_min, const XY& ac) const
  193. {
  194.   XY ac_nearest(0, 0);
  195.   iterator i;
  196.   TRAVERSE(*this, i) {
  197.     int r = maximum(i->width() / 2, uint(ac_min));
  198.     if(compare_distance_lt(ac, i->ac_s(), r)) {
  199.       ac_nearest = i->ac_s();
  200.       break;
  201.     }
  202.     if(compare_distance_lt(ac, i->ac_e(), r)) {
  203.       ac_nearest = i->ac_e();
  204.       break;
  205.     }
  206.   }
  207.   return ac_nearest;
  208. }
  209.  
  210. LINE_ELEMENT* LINE_LIST::search(XYT eps, const XY& ac)
  211. {
  212.   LINE_ELEMENT* p = NULL;
  213.   iterator i;
  214.   TRAVERSE(*this, i) {
  215.     if(i->is_on_line(eps, ac)) {
  216.       p = &*i;
  217.       break;
  218.     }
  219.   }
  220.   return p;
  221. }
  222.  
  223. int LINE_LIST::purge_vertical_lines(LINE_ELEMENT& line)
  224. {
  225.   int vcount = 0;
  226.   iterator i;
  227.   TRAVERSE(*this, i) {
  228.     LINE_ELEMENT& current = *i;
  229.     if((current.is_vertical()                )
  230.     && (line.ac_s().x() == current.ac_s().x())
  231.     && (line.width()    == current.width()   )) {
  232.       XYT min_a = minimum(line.ac_s().y(), line.ac_e().y());
  233.       XYT max_a = maximum(line.ac_s().y(), line.ac_e().y());
  234.       XYT min_b = minimum(current.ac_s().y(), current.ac_e().y());
  235.       XYT max_b = maximum(current.ac_s().y(), current.ac_e().y());
  236.       if((max_a < min_b) || (max_b < min_a)) {
  237.         // do nothing
  238.       } else {
  239.         XYT actual_min = minimum(min_a, min_b);
  240.         XYT actual_max = maximum(max_a, max_b);
  241.         line.set_ac_s(XY(line.ac_s().x(), actual_min));
  242.         line.set_ac_e(XY(line.ac_s().x(), actual_max));
  243.         iterator current_i = i--;
  244.         erase(current_i);
  245.         vcount++;
  246.       }
  247.     }
  248.   }
  249.   return vcount;
  250. }
  251.  
  252. int LINE_LIST::purge_holizontal_lines(LINE_ELEMENT& line)
  253. {
  254.   int hcount = 0;
  255.   iterator i;
  256.   TRAVERSE(*this, i) {
  257.     LINE_ELEMENT& current = *i;
  258.     if((current.is_holizontal()              )
  259.     && (line.ac_s().y() == current.ac_s().y())
  260.     && (line.width()    == current.width()   )) {
  261.       XYT min_a = minimum(line.ac_s().x(), line.ac_e().x());
  262.       XYT max_a = maximum(line.ac_s().x(), line.ac_e().x());
  263.       XYT min_b = minimum(current.ac_s().x(), current.ac_e().x());
  264.       XYT max_b = maximum(current.ac_s().x(), current.ac_e().x());
  265.       if((max_a < min_b) || (max_b < min_a)) {
  266.         // do nothing
  267.       } else {
  268.         XYT actual_min = minimum(min_a, min_b);
  269.         XYT actual_max = maximum(max_a, max_b);
  270.         line.set_ac_s(XY(actual_min, line.ac_s().y()));
  271.         line.set_ac_e(XY(actual_max, line.ac_s().y()));
  272.         iterator current_i = i--;
  273.         erase(current_i);
  274.         hcount++;
  275.       }
  276.     }
  277.   }
  278.   return hcount;
  279. }
  280.  
  281. int LINE_LIST::purge_slash_lines(LINE_ELEMENT& line)
  282. {
  283.   int scount = 0;
  284.   iterator i;
  285.   TRAVERSE(*this, i) {
  286.     LINE_ELEMENT& current = *i;
  287.     const XY& ac_p1 = line.ac_s();
  288.     const XY& ac_p2 = current.ac_s();
  289.     if((current.is_slash()                                )
  290.     && ((ac_p1.x() - ac_p1.y()) == (ac_p2.x() - ac_p2.y()))
  291.     && (line.width()    == current.width()                )) {
  292.       XYT min_a = minimum(line.ac_s().x(), line.ac_e().x());
  293.       XYT max_a = maximum(line.ac_s().x(), line.ac_e().x());
  294.       XYT min_b = minimum(current.ac_s().x(), current.ac_e().x());
  295.       XYT max_b = maximum(current.ac_s().x(), current.ac_e().x());
  296.       if((max_a < min_b) || (max_b < min_a)) {
  297.         // do nothing
  298.       } else {
  299.         XYT actual_min = minimum(min_a, min_b);
  300.         XYT actual_max = maximum(max_a, max_b);
  301.         line.set_ac_s(XY(actual_min, actual_min - ac_p1.x() + ac_p1.y()));
  302.         line.set_ac_e(XY(actual_max, actual_max - ac_p1.x() + ac_p1.y()));
  303.         iterator current_i = i--;
  304.         erase(current_i);
  305.         scount++;
  306.       }
  307.     }
  308.   }
  309.   return scount;
  310. }
  311.  
  312. int LINE_LIST::purge_backslash_lines(LINE_ELEMENT& line)
  313. {
  314.   int bcount = 0;
  315.   iterator i;
  316.   TRAVERSE(*this, i) {
  317.     LINE_ELEMENT& current = *i;
  318.     const XY& ac_p1 = line.ac_s();
  319.     const XY& ac_p2 = current.ac_s();
  320.     if((current.is_backslash()                            )
  321.     && ((ac_p1.x() + ac_p1.y()) == (ac_p2.x() + ac_p2.y()))
  322.     && (line.width()    == current.width()                )) {
  323.       XYT min_a = minimum(line.ac_s().x(), line.ac_e().x());
  324.       XYT max_a = maximum(line.ac_s().x(), line.ac_e().x());
  325.       XYT min_b = minimum(current.ac_s().x(), current.ac_e().x());
  326.       XYT max_b = maximum(current.ac_s().x(), current.ac_e().x());
  327.       if((max_a < min_b) || (max_b < min_a)) {
  328.         // do nothing
  329.       } else {
  330.         XYT actual_min = minimum(min_a, min_b);
  331.         XYT actual_max = maximum(max_a, max_b);
  332.         line.set_ac_s(XY(actual_min, - actual_min + ac_p1.x() + ac_p1.y()));
  333.         line.set_ac_e(XY(actual_max, - actual_max + ac_p1.x() + ac_p1.y()));
  334.         iterator current_i = i--;
  335.         erase(current_i);
  336.         bcount++;
  337.       }
  338.     }
  339.   }
  340.   return bcount;
  341. }
  342.  
  343. int LINE_LIST::purge_lines()
  344. {
  345.   LINE_LIST hline_list;
  346.   LINE_LIST vline_list;
  347.   LINE_LIST sline_list;
  348.   LINE_LIST bline_list;
  349.   LINE_LIST oline_list;
  350.   int count = 0;
  351.  
  352.   iterator i;
  353.   TRAVERSE(*this, i) {
  354.     LINE_ELEMENT& current = *i;
  355.     if(i->is_vertical()) {
  356.       count += vline_list.purge_vertical_lines(*i);
  357.       vline_list.push_back(*i);
  358.     } else if(i->is_holizontal()) {
  359.       count += hline_list.purge_holizontal_lines(*i);
  360.       hline_list.push_back(*i);
  361.     } else if(i->is_slash()) {
  362.       count += sline_list.purge_slash_lines(*i);
  363.       sline_list.push_back(*i);
  364.     } else if(i->is_backslash()) {
  365.       count += bline_list.purge_backslash_lines(*i);
  366.       bline_list.push_back(*i);
  367.     } else {
  368.       oline_list.push_back(*i);
  369.     }
  370.   }
  371.   clear();
  372.   add(hline_list);
  373.   add(vline_list);
  374.   add(sline_list);
  375.   add(bline_list);
  376.   add(oline_list);
  377.   return count;
  378. }
  379.  
  380. void LINE_LIST::rotate_90()
  381. {
  382.   iterator i;
  383.   TRAVERSE(*this, i) {
  384.     i->rotate_90();
  385.   }
  386. }
  387.